//todo 自行封装 request 
/* 
    1. 封装数据请求
    2. 理由
        1. 统一数据请求的处理 
        2. 考虑底层库将来可能会切换
        3. 数据请求可能设计到一些业务逻辑
    3. 数据请求封装
        1. 第三方有提供类型的，但是呢你不知道
        2. 整体思维
            1. timeout  + baseURL
            2. 拦截器
            3. request函数的封装
                1. 对参数的类型，对返回值的类型做约定
                2. 通过method不同，做对应的switch操作
*/

import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";
import qs from "qs";
import * as cookie from "./index";

//todo 创建自定义请求实例
const ins: AxiosInstance = axios.create({
  timeout: 20000,
  baseURL: "http://59.110.226.77:5000/api/private/v1/",
});

//todo 拦截器
ins.interceptors.request.use(
  (config: AxiosRequestConfig): AxiosRequestConfig => {
    //todo 携带token
    const token: string | undefined = cookie.getCookie("token");
    config.headers.common["Authorization"] = token;
    return config;
  },
  (error: any): Promise<any> => {
    return Promise.reject(error);
  }
);

ins.interceptors.response.use(
  (res: AxiosResponse<any>): AxiosResponse<any> => {
    return res.data;
  },
  (error: any): Promise<any> => {
    return Promise.reject(error);
  }
);

interface IConfig {
  url: string;
  method?: string;
  data?: {
    [key: string]: any;
  };
  postType?: string;
}
const request = ({
  url,
  method = "GET",
  data,
  postType = "form",
}: IConfig): Promise<AxiosResponse<any>> => {
  // 根据请求的类型来进行划分
  switch (method.toLocaleLowerCase()) {
    case "post":
      if (postType === "file") {
        const p: FormData = new FormData(); //文件
        for (const key in data) {
          // 将data的所有参数全部给了p
          p.append(key, data[key]);
        }
        return ins.post(url, p);
      }
      return ins.post(url, qs.stringify(data));
    case "put":
      return ins.put(url, data);
    case "delete":
      return ins.delete(url, { data });
    case "patch":
      return ins.patch(url, data);
    default:
      return ins.get(url, { params: data });
  }
};

export default request;
